use serde::{Deserialize, Serialize};
use std::fmt;

/// 方向枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Direction {
    /// 向上
    Up,
    /// 向下
    Down,
}

impl fmt::Display for Direction {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Direction::Up => write!(f, "向上"),
            Direction::Down => write!(f, "向下"),
        }
    }
}

impl Direction {
    /// 获取相反方向
    pub fn opposite(&self) -> Direction {
        match self {
            Direction::Up => Direction::Down,
            Direction::Down => Direction::Up,
        }
    }
}

/// 频率枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, Ord, PartialOrd)]
pub enum Freq {
    /// 1分钟
    Min1 = 0,
    /// 5分钟
    Min5 = 1,
    /// 15分钟
    Min15 = 2,
    /// 30分钟
    Min30 = 3,
    /// 60分钟
    Min60 = 4,
    /// 日线
    Day = 5,
    /// 周线
    Week = 6,
    /// 月线
    Month = 7,
    /// 季线
    Quarter = 8,
    /// 年线
    Year = 9,
}

impl fmt::Display for Freq {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Freq::Min1 => write!(f, "1分钟"),
            Freq::Min5 => write!(f, "5分钟"),
            Freq::Min15 => write!(f, "15分钟"),
            Freq::Min30 => write!(f, "30分钟"),
            Freq::Min60 => write!(f, "60分钟"),
            Freq::Day => write!(f, "日线"),
            Freq::Week => write!(f, "周线"),
            Freq::Month => write!(f, "月线"),
            Freq::Quarter => write!(f, "季线"),
            Freq::Year => write!(f, "年线"),
        }
    }
}

impl Freq {
    /// 从字符串创建频率
    pub fn from_str(s: &str) -> Option<Self> {
        match s {
            "1分钟" => Some(Freq::Min1),
            "5分钟" => Some(Freq::Min5),
            "15分钟" => Some(Freq::Min15),
            "30分钟" => Some(Freq::Min30),
            "60分钟" => Some(Freq::Min60),
            "日线" => Some(Freq::Day),
            "周线" => Some(Freq::Week),
            "月线" => Some(Freq::Month),
            "季线" => Some(Freq::Quarter),
            "年线" => Some(Freq::Year),
            _ => None,
        }
    }

    /// 获取频率的秒数
    pub fn seconds(&self) -> u64 {
        match self {
            Freq::Min1 => 60,
            Freq::Min5 => 300,
            Freq::Min15 => 900,
            Freq::Min30 => 1800,
            Freq::Min60 => 3600,
            Freq::Day => 86400,
            Freq::Week => 604800,
            Freq::Month => 2592000,
            Freq::Quarter => 7776000,
            Freq::Year => 31536000,
        }
    }
}

/// 分型标记枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Mark {
    /// 顶分型
    G,
    /// 底分型
    D,
}

impl fmt::Display for Mark {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Mark::G => write!(f, "顶分型"),
            Mark::D => write!(f, "底分型"),
        }
    }
}

/// 操作枚举
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum Operate {
    /// 开多
    Long = 0,
    /// 开空
    Short = 1,
    /// 平多
    CloseLong = 2,
    /// 平空
    CloseShort = 3,
    /// 持有
    Hold = 4,
}

impl fmt::Display for Operate {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Operate::Long => write!(f, "开多"),
            Operate::Short => write!(f, "开空"),
            Operate::CloseLong => write!(f, "平多"),
            Operate::CloseShort => write!(f, "平空"),
            Operate::Hold => write!(f, "持有"),
        }
    }
}

impl Operate {
    /// 从字符串创建操作
    pub fn from_str(s: &str) -> Option<Self> {
        match s {
            "开多" => Some(Operate::Long),
            "开空" => Some(Operate::Short),
            "平多" => Some(Operate::CloseLong),
            "平空" => Some(Operate::CloseShort),
            "持有" => Some(Operate::Hold),
            _ => None,
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_direction_display() {
        assert_eq!(Direction::Up.to_string(), "向上");
        assert_eq!(Direction::Down.to_string(), "向下");
    }

    #[test]
    fn test_freq_display() {
        assert_eq!(Freq::Min1.to_string(), "1分钟");
        assert_eq!(Freq::Min5.to_string(), "5分钟");
        assert_eq!(Freq::Day.to_string(), "日线");
        assert_eq!(Freq::Year.to_string(), "年线");
    }

    #[test]
    fn test_mark_display() {
        assert_eq!(Mark::G.to_string(), "顶分型");
        assert_eq!(Mark::D.to_string(), "底分型");
    }

    #[test]
    fn test_operate_display() {
        assert_eq!(Operate::Long.to_string(), "开多");
        assert_eq!(Operate::Short.to_string(), "开空");
        assert_eq!(Operate::CloseShort.to_string(), "平空");
    }
} 